using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace HappyTemplate
{
	public abstract class LexerBase<TToken, TTokenType, TErrorCollector> where TErrorCollector : ErrorCollectorBase, new()
	{
		readonly TErrorCollector _errorCollector;
		//public LexerErrorCollector ErrorCollector { get { return _errorCollector; } } 
		readonly List<TToken> _readAhead = new List<TToken>();
		readonly InputReader _reader;

		protected abstract TToken ExtractToken();

		public LexerBase(TextReader reader, string fileName, SourceErrorCollection errs)
			: this(new InputReader(reader, fileName), errs)
		{
		}

		public LexerBase(InputReader reader, SourceErrorCollection errs)
		{
			_reader = reader;
			_errorCollector = new TErrorCollector();
			_errorCollector.SourceErrors = errs;
			_reader.EatWhite();
		}

		public bool Eof { get { return _readAhead.Count == 0 ? _reader.Eof : false; } }

		public TToken PeekToken()
		{
			return PeekToken(0);
		}
		public TToken PeekToken(int lookAheadDepth)
		{
			while (_readAhead.Count <= lookAheadDepth)
				_readAhead.Add(ExtractToken());

			return _readAhead[lookAheadDepth];
		}

		public TToken NextToken()
		{
			TToken retval;
			if (_readAhead.Count > 0)
			{
				retval = _readAhead[0];
				_readAhead.RemoveAt(0);
			}
			else
			{
				return ExtractToken();
			}
			return retval;
		}
	}
}
